import random
import time

from ads_api import AdsApi
from constants.global_variable import password_chars, logger
from task.cultivating_accounts_task import CultivatingAccountsTask
from utils.email_utils import EmailUtils
from utils.faker_utils import FakerUtils
from utils.selenium_utils import SeleniumUtils
from utils.web_driver_utils import WebDriverUtils


class AdsInsRegisterTask:
    def __init__(self):
        self.web_driver = None
        self.email_info = None
        self.last_sms_code = ''

    def run(self):
        profile_id = AdsApi.create_browser()['data']['profile_id']
        logger.info(f'创建的环境id为：{profile_id}')
        self.web_driver = AdsApi.start_browser(profile_id)
        time.sleep(1)
        self.web_driver.get("https://www.instagram.com/")
        time.sleep(3)
        # 开始注册
        self.start_register()
        # 注册成功相关弹窗处理
        self.handle_success_popups()
        # 养号
        self.handle_cultivating_accounts()

        # session_id = self.web_driver.get_cookie('sessionid')
        # print(f'获取的session_id为{session_id}')
        print('Done')

    def start_register(self):
        logger.info('即将开始注册步骤')
        register_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '注册')
        time.sleep(5)
        if not register_btn:
            logger.info('ins阻塞，即将刷新页面')
            self.web_driver.refresh()  # 刷新页面
            time.sleep(5)
        # 允许使用cookie
        accept_cookie_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '允许使用所有 Cookie')
        if accept_cookie_btn:
            self.web_driver.execute_script("arguments[0].click();", accept_cookie_btn)
            time.sleep(5)
        # 点击注册按钮
        register_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '注册')
        if register_btn:
            self.web_driver.execute_script("arguments[0].click();", register_btn)
            time.sleep(5)
        # 点击使用邮箱注册
        email_register_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '邮箱')
        if email_register_btn:
            self.web_driver.execute_script("arguments[0].click();", email_register_btn)
            time.sleep(5)
            self.email_tab_register()
        else:
            use_email_register_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '使用邮箱注册')
            if use_email_register_btn:
                self.web_driver.execute_script("arguments[0].click();", use_email_register_btn)
                time.sleep(5)
                self.email_button_register()
            else:
                # 既不是页签式注册，也不是底部按钮注册
                logger.error('注册失败，未识别到邮箱注册按钮')
                raise RuntimeError('注册失败，未识别到邮箱注册按钮')


    def input_name_and_password(self):
        # 输入用户名
        full_name_input = WebDriverUtils.find_element_by_name(self.web_driver, 'fullName')
        if full_name_input:
            self.web_driver.execute_script("arguments[0].click();", full_name_input)
            time.sleep(0.5)
            full_name = FakerUtils.get_fake_name()
            logger.info(f'生成的全名为：{full_name}')
            SeleniumUtils.human_typing(full_name_input, full_name)
        else:
            logger.error('全名输入框未找到')
        # 输入密码
        password_input = WebDriverUtils.find_element_by_name(self.web_driver, 'password')
        if password_input:
            self.web_driver.execute_script("arguments[0].click();", password_input)
            time.sleep(0.5)
            password = ''.join(random.choice(password_chars) for _ in range(10))
            logger.info(f'生成的密码为：{password}')
            SeleniumUtils.human_typing(password_input, password)
            time.sleep(0.5)
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
            time.sleep(5)
        else:
            logger.error('输入全名和密码的下一步未找到')

    def email_tab_register(self):
        logger.info('进入邮箱页签式注册')
        # 找到邮箱输入框点击并输入邮箱
        email_input = WebDriverUtils.find_element_by_name(self.web_driver, 'email')
        if email_input:
            self.web_driver.execute_script("arguments[0].click();", email_input)
            time.sleep(1.5)
            self.get_email_and_input(email_input)
            time.sleep(1.5)
        else:
            logger.error('邮箱输入框未找到')
        # 点击下一步
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
            time.sleep(5)
        else:
            logger.error('输入邮箱后下一步按钮未找到')
        # 获取并输入验证码
        logger.info('即将开始获取验证码')
        sms_code = EmailUtils.get_register_email_code(self.email_info, self.last_sms_code)
        if len(sms_code) != 6:
            # 重发验证码
            resend_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '重发验证码')
            if resend_btn:
                self.web_driver.execute_script("arguments[0].click();", resend_btn)
                time.sleep(5)
                sms_code = EmailUtils.get_register_email_code(self.email_info, self.last_sms_code)
                if len(sms_code) != 6:
                    logger.error('重发验证码后还是获取不到验证码, 判断注册失败')
                    raise RuntimeError('重发验证码后还是没收到验证码, 判断注册失败')
        sms_code_input = WebDriverUtils.find_element_by_name(self.web_driver, 'emailConfirmationCode')
        if sms_code_input:
            self.web_driver.execute_script("arguments[0].click();", sms_code_input)
            time.sleep(1.5)
            SeleniumUtils.human_typing(sms_code_input, sms_code)
            time.sleep(1.5)
        # 点击下一步
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
            time.sleep(5)
        else:
            logger.error('输入验证码后下一步按钮未找到')
        # 输入全名和密码
        self.input_name_and_password()
        # 设置生日
        self.set_birthday()
        # 点击下一步
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
            time.sleep(8)
        else:
            logger.error('注册最后一步下一步点击按钮没找到')
        # 等待8s后如果还是卡主直接刷新页面
        ins_art_svg = WebDriverUtils.find_element_by_css(self.web_driver, 'svg[aria-label="Instagram"]')
        if not ins_art_svg:
            self.web_driver.refresh()
            time.sleep(5)
            ins_art_svg = WebDriverUtils.find_element_by_css(self.web_driver, 'svg[aria-label="Instagram"]')
            if not ins_art_svg:
                logger.error('刷新页面后还是没找到ins艺术字，认定注册失败')
                raise RuntimeError('刷新页面后还是没找到ins艺术字，认定注册失败')
        logger.info('注册成功')


    def email_button_register(self):
        logger.info('进入邮箱底部按钮式注册')
        email_input = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '邮箱')
        if email_input:
            self.web_driver.execute_script("arguments[0].click();", email_input)
            time.sleep(1.5)
            self.get_email_and_input(email_input)
            time.sleep(1.5)
        else:
            logger.error('邮箱输入框未找到')
        # 点击下一步
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
            time.sleep(3)
        else:
            logger.error('输入邮箱后下一步按钮未找到')
        # 获取并输入验证码
        logger.info('即将开始获取验证码')
        sms_code = EmailUtils.get_register_email_code(self.email_info, self.last_sms_code)
        if len(sms_code) != 6:
            # 重发验证码
            resend_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '我没有收到验证码')
            if resend_btn:
                self.web_driver.execute_script("arguments[0].click();", resend_btn)
                time.sleep(5)
                sms_code = EmailUtils.get_register_email_code(self.email_info, self.last_sms_code)
                if len(sms_code) != 6:
                    logger.error('重发验证码后还是获取不到验证码, 判断注册失败')
                    raise RuntimeError('重发验证码后还是没收到验证码, 判断注册失败')
        sms_code_input = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '验证码')
        if sms_code_input:
            self.web_driver.execute_script("arguments[0].click();", sms_code_input)
            time.sleep(1.5)
            SeleniumUtils.human_typing(sms_code_input, sms_code)
            time.sleep(1.5)
        else:
            logger.error('验证码输入框未找到')
        # 点击下一步
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
        # 创建密码
        password_input = WebDriverUtils.find_elements_with_text(self.web_driver, 'input', '密码')
        if password_input:
            self.web_driver.execute_script("arguments[0].click();", password_input)
            time.sleep(1.5)
            password = ''.join(random.choice(password_chars) for _ in range(10))
            logger.info(f'生成的密码为：{password}')
            SeleniumUtils.human_typing(password_input, password)
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
        # 设置出生日期 非下拉选项
        # 你的姓名 全名
        full_name_input = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '全名')
        if full_name_input:
            self.web_driver.execute_script("arguments[0].click();", full_name_input)
            time.sleep(1.5)
            full_name = FakerUtils.get_fake_name()
            logger.info(f'生成的全名为：{full_name}')
            SeleniumUtils.human_typing(full_name_input, full_name)
            time.sleep(1.5)
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
        # 创建账号
        next_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '下一步')
        if next_btn:
            self.web_driver.execute_script("arguments[0].click();", next_btn)
        # 我同意
        agree_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'span', '我同意')
        if agree_btn:
            self.web_driver.execute_script("arguments[0].click();", agree_btn)

    def set_birthday(self):
        year_select = WebDriverUtils.find_element_by_css(self.web_driver, 'select[title="年："]')
        SeleniumUtils.random_select_age(year_select)
        time.sleep(0.5)
        month_select = WebDriverUtils.find_element_by_css(self.web_driver, 'select[title="月："]')
        SeleniumUtils.random_select(month_select)
        time.sleep(0.3)
        day_select = WebDriverUtils.find_element_by_css(self.web_driver, 'select[title="日："]')
        SeleniumUtils.random_select(day_select)
        time.sleep(2)
        next_step_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'button', '下一步')
        self.web_driver.execute_script("arguments[0].click();", next_step_btn)
        time.sleep(5)

    def handle_success_popups(self):
        # 绑定facebook、添加头像、下载ins应用、添加手机号
        while True:
            home_page_svg = WebDriverUtils.find_element_by_css(self.web_driver, 'svg[aria-label="首页"]')
            if home_page_svg:
                break
            # 检查是否出现跳过按钮
            skip_btn = WebDriverUtils.find_elements_with_text(self.web_driver, 'div', '跳过')
            if skip_btn:
                self.web_driver.execute_script("arguments[0].click();", skip_btn)
                time.sleep(2)

    def handle_cultivating_accounts(self):
        task = CultivatingAccountsTask(self.web_driver)
        task.run()

    def get_email_and_input(self, email_input):
        self.email_info = EmailUtils.get_email()
        logger.info(f'获取的邮箱信息为：{self.email_info.to_string()}')
        SeleniumUtils.human_typing(email_input, self.email_info.email_address)
        self.get_last_sms_code()

    def get_last_sms_code(self):
        # 输入邮箱前取上一次的验证码
        sms_code = EmailUtils.request_sms_code(self.email_info)
        if len(sms_code) == 6:
            self.last_sms_code = sms_code
        logger.info(f'获取到的上一次验证码为：{self.last_sms_code}')